/*
 * bw_IpIn.cpp
 *
 *  Created on: 2018年11月9日
 *      Author: linsainan
 */

#include "bw_IpIn.h"
#include "public.h"
#include "cJSON.h"
#include "bw_FcgiRequest.h"
#include "bw_jskey.h"
#include "bw_sys.h"
#include "bw_public.h"

using namespace bwcgi;

extern char g_outbuf[];
extern cJSON *retMesgHead(cJSON *root,unsigned int retcode,const char *retmsg);

int jsonMsgtoStr(cJSON *pout_root,char *gbuf,unsigned int maxsize)
{
	if(!pout_root || !gbuf)
	{
		return 1;
	}

	char* str = cJSON_PrintUnformatted(pout_root);
	snprintf(gbuf, maxsize,"%s",str);
	free(str);

	return 0;
}
// IP输入获取
int getInputIpInfo(InputIp *pinip)
{
	int i = 0;
	int j = 0;
	stENC_IPINSET* ip_info = NULL;
	InputIp *item = NULL;

	if(!pinip)
	{
		return 0;
	}

	j = 0;
	for (i = 0; i < ENC_MAX_IPINPUT_NUM; i++) 
	{
		ip_info = &(g_encset_mst->enc_ipin[i]);
		if (!ip_info->inp_enable) 
		{
			continue;
		}

		item = &(pinip[j]);

		item->index = j + 1;
		item->ip = Addr_swap(ip_info->inp_ethio.ethio_dipaddr);
		item->port = ip_info->inp_ethio.ethio_dipport;
		item->protocol = ip_info->inp_proto;
		item->rate = ip_info->inp_ethio.ethio_bitrates;

		j++;
	}
	
	return j;
}
const char* ip_list_reponse(PAGE_QUERY query)
{
	cJSON *pout_root = NULL;
	cJSON *p_obj = NULL;
	cJSON *p_arr = NULL;
	cJSON *p_tmp = NULL;
	char tmpbuf[50] = {0};
	int i = 0;
	int pos = 0;
	int len = 0;
	InputIp ipinfo[ENC_MAX_IPINPUT_NUM];
	InputIp *item = NULL;

	len = getInputIpInfo(ipinfo);

	pout_root = cJSON_CreateObject();
	p_obj = retMesgHead(pout_root,0,"SUCCESS");

	sprintf(tmpbuf,"%d",len);
	cJSON_AddStringToObject( p_obj, "total", tmpbuf);
	
	p_arr = cJSON_CreateArray();
	cJSON_AddItemToObject(p_obj, "ip_list", p_arr);

	for (i =0; i < query.count; i++) 
	{
		pos = i + query.count * (query.page - 1);
		
		if(pos >= len)
		{
			break;		
		}

		item = &(ipinfo[pos]);
		
		p_tmp = cJSON_CreateObject();
		cJSON_AddItemToArray(p_arr, p_tmp);
		
		cJSON_AddNumberToObject(p_tmp, "id", item->index);
		
		// ip
		sprintf(tmpbuf, "%s", iptostr(item->ip));
		cJSON_AddStringToObject(p_tmp, "ip", tmpbuf);
		// port
		cJSON_AddNumberToObject(p_tmp, "port",item->port);
		// protocol
		sprintf(tmpbuf, "%d", item->protocol);
		cJSON_AddStringToObject(p_tmp, "protocol", tmpbuf);
		// code_rate
		sprintf(tmpbuf, "%d", item->rate);
		cJSON_AddStringToObject(p_tmp, "code_rate",tmpbuf);
	}

	jsonMsgtoStr(pout_root,g_outbuf,get_g_oubuf_size());
	
	cJSON_Delete(pout_root);
	return g_outbuf;
}

const char* ip_list(const char* json) 
{
	cJSON *p_root = NULL;
	cJSON *p_para = NULL;
	cJSON *p_tmp = NULL;
	eENC_ERROR code = BWENC_ERROR_NONE;
	PAGE_QUERY query;

	p_root = cJSON_Parse(json);
	if (p_root == NULL)
	{
		cgi_debug("parse para error");
		goto error;
	}

	p_para = cJSON_GetObjectItem(p_root, "param");
	if(p_para == NULL)
	{
		cgi_debug("parse para error");
		goto error;
	}

	memset(&query,0,sizeof(query));
	p_tmp = cJSON_GetObjectItem(p_para, "page");
	if(NULL != p_tmp)
	{
		query.page = atoi(p_tmp->valuestring);
	}
	else
	{
		cgi_debug("parse pase error");
		code = BWENC_ERROR_INVALID_PARAM;
		goto error;
	}

	query.page = query.page < 1 ? 1 : query.page;
	p_tmp = cJSON_GetObjectItem(p_para, "count");
	if(NULL != p_tmp)
	{
		query.count = atoi(p_tmp->valuestring);
	}
	else
	{
		cgi_debug("parse count error");
		code = BWENC_ERROR_INVALID_PARAM;
		goto error;
	}

	cJSON_Delete(p_root);
	return ip_list_reponse(query);
	
error:	
	cJSON_Delete(p_root);
	return bwenc_common_ack(code);
}

// IP输入新建/编辑
const char* ip_edit(const char* json) 
{
	eENC_ERROR code = BWENC_ERROR_UNKNOW;
	cJSON* root = cJSON_Parse(json);
	if (!root) 
	{
		cgi_debug("error");
		code = BWENC_ERROR_INVALID_PARAM;
		return bwenc_common_ack(code);
	}

	cJSON* param = cJSON_GetObjectItem(root, KEY_PARAM);
	if (!param) 
	{
		cgi_debug("error");
		code = BWENC_ERROR_INVALID_PARAM;
		cJSON_Delete(root);
		return bwenc_common_ack(code);
	}

	// id
	int id = -1;
	cJSON *p_tmp = cJSON_GetObjectItem(param, "id");
	if (p_tmp && p_tmp->valueint > 0 && p_tmp->valueint <= ENC_MAX_IPINPUT_NUM) 
	{
		id = p_tmp->valueint - 1;
	}

	// ip
	p_tmp = cJSON_GetObjectItem(param, "ip");
	if (!p_tmp || !p_tmp->valuestring || strlen(p_tmp->valuestring) <= 0) 
	{
		cgi_debug("ip error");
		code = BWENC_ERROR_INVALID_PARAM;
		cJSON_Delete(root);
		return bwenc_common_ack(code);
	}
	unsigned int ip = Addr_swap(ipstrtoint(p_tmp->valuestring));

	// port
	p_tmp = cJSON_GetObjectItem(param, "port");
	if (!p_tmp || p_tmp->valueint < 0 || p_tmp->valueint > BWENC_PORT_MAX) 
	{
		cgi_debug("port error");
		code = BWENC_ERROR_INVALID_PARAM;
		cJSON_Delete(root);
		return bwenc_common_ack(code);
	}
	
	unsigned short port = p_tmp->valueint;

	if (0 == in_ip_repeat(id, ip, port)) 
	{
		cgi_debug("ip port repeat,ip:%d,port:%d", ip, port);
		code = BWENC_ERROR_IP_REPEAT;
		cJSON_Delete(root);
		return bwenc_common_ack(code);
	}

	cgi_debug("index:%d, ip:%x,port:%d",id,ip,port);
	
	stENC_IPINSET* ip_info = NULL;
	char log_str[SZ_1K];
	if (id == -1) 
	{
		for (int i = 0; i < ENC_MAX_IPINPUT_NUM; i++) 
		{
			ip_info = &(g_encset_mst->enc_ipin[i]);
			if (!ip_info->inp_enable) 
			{
				break;
			}
		}
		if (ip_info == NULL) 
		{
			cgi_debug("ip num more than max value,ip:%d,port:%d", ip, port);
			code = BWENC_ERROR_IP_NUM_OVAERFLOW;
			cJSON_Delete(root);
			return bwenc_common_ack(code);
		}
		sprintf(log_str,"%s","IP Input added successfully");
	} 
	else 
	{
		ip_info = &(g_encset_mst->enc_ipin[id]);
		sprintf(log_str,"%s","IP Input modified successfully");
	}

	sem_wait(g_shrmsem);
	ip_info->inp_ethio.ethio_dipaddr = ip;
	ip_info->inp_ethio.ethio_dipport = port;
	ip_info->inp_proto = 0;//0,udp;
	ip_info->inp_enable = 1;
	
	g_encset_mst->enc_setvsion++;
	sem_post(g_shrmsem);

	
	log_write(BWENC_LOG_SYS_SET, log_str);

	cJSON_Delete(root);
	return bwenc_common_ack(BWENC_ERROR_NONE);
}

int in_ip_repeat(int id, unsigned int ip, unsigned short port) 
{
	stENC_IPINSET* ip_info = NULL;

	for (int i = 0; i < ENC_MAX_IPINPUT_NUM; i++) 
	{
		ip_info = &(g_encset_mst->enc_ipin[i]);
		if (!ip_info->inp_enable) 
		{
			continue;
		}
		
		if (id != i && ip_info->inp_ethio.ethio_sipaddr == ip
				&& ip_info->inp_ethio.ethio_sipport == port) 
		{
			return 0;
		}
	}

	return 1;
}

//获取ip输入通道数
int getInputIpTotal()
{
	int i = 0;
	int j = 0;
	stENC_IPINSET* ip_info = NULL;

	for (i = 0; i < ENC_MAX_IPINPUT_NUM; i++) 
	{
		ip_info = &(g_encset_mst->enc_ipin[i]);
		if (!ip_info->inp_enable) 
		{
			continue;
		}

		j++;
	}
	
	return j;
}

//ip输入，删除
int del_inputip(unsigned int ip_ch)
{
	if(0 == ip_ch || ip_ch > ENC_MAX_IPINPUT_NUM)
	{
		return 1;
	}

	int index = 0;	
	int next_index = 0;
	int total = 0;
	stENC_IPINSET tmp_inip[ENC_MAX_IPINPUT_NUM];
	stENC_IPINSET* ip_info = NULL;

	index = ip_ch - 1;
	next_index = ip_ch;
	total = getInputIpTotal();

	ip_info = &(g_encset_mst->enc_ipin[next_index]);
	memcpy(tmp_inip,ip_info, (total - ip_ch) * sizeof(stENC_IPINSET));

	ip_info = &(g_encset_mst->enc_ipin[index]);
	memset(ip_info,0,(total - ip_ch + 1) * sizeof(stENC_IPINSET));

	ip_info = &(g_encset_mst->enc_ipin[index]);
	memcpy(ip_info,tmp_inip, (total - ip_ch) * sizeof(stENC_IPINSET));
	
	return 0;
}

const char* in_ip_del(const char* json) 
{
	cJSON *p_root = NULL;
	cJSON *p_para = NULL;
	cJSON *p_tmp = NULL;
	int id = 0;
	eENC_ERROR code = BWENC_ERROR_NONE;
	
	p_root = cJSON_Parse(json);
	if (p_root == NULL)
	{
		cgi_debug("parse para error");
		return bwenc_common_ack(BWENC_ERROR_INVALID_PARAM);
	}

	p_para = cJSON_GetObjectItem(p_root, "param");
	if(p_para == NULL)
	{
		cgi_debug("parse para error");
		code = BWENC_ERROR_INVALID_PARAM;
		goto error;
	}

	// id	
	p_tmp = cJSON_GetObjectItem(p_para, "id");
	if (p_tmp && p_tmp->valueint > 0 && p_tmp->valueint <= ENC_MAX_IPINPUT_NUM) 
	{
		id = p_tmp->valueint;
	}
	else
	{
		code = BWENC_ERROR_INVALID_PARAM;
		goto error;
	}

	code = (eENC_ERROR)del_inputip(id);
error:	
	cJSON_Delete(p_root);
	return bwenc_common_ack(code);
}

